#!/usr/bin/env python
#coding=utf-8
import json, time
from hashlib import md5, sha256
from sqlalchemy import and_, or_, not_

from flask import Blueprint, session, request, render_template, make_response, g, url_for, redirect
from flask.ext.sqlalchemy import Pagination

from codingabc.database import db
from codingabc.response import ResponseJson
from app.helpers.date_time import str2timestamp
from app.helpers.common import easy_query_filter, get_params
from codingabc.helpers import toint, get_count, log_info, randomstr, log_debug, ismobile, randomstr, current_app

from app.models.role import Role, RoleMenu, RolePermission
from app.models.menu import Menu
from app.models.user import User, UserAdmin, UserPassword, UserPermission
from app.models.sys import SysRegion
from app.services.get_data import role_name, get_role_list, user_role_id_list, get_user_name, get_main_permission_name, get_menu_name

resjson = ResponseJson()
resjson.module_code = 16

power = Blueprint('power', __name__)



@power.route('/menu_sort/modify')
def menu_sort_modify():
    """菜单列表排序"""

    menu_id = toint(request.args.get('menu_id', '0'))
    new_sort = toint(request.args.get('new_sort', '0'))
    new_sort = new_sort if new_sort > 0 else -1

    if new_sort < 0:
        return u'只能输入大于0的数字'

    if new_sort > 10000000:
        return u'数字不能过大'

    if menu_id <= 0:
        return u'参数出错'

    m = Menu.get(menu_id)

    if m:
        m.update(sort_order=new_sort, commit=True)

    return u'ok'


@power.route('/admin_add', methods=['GET', 'POST'])
@power.route('/admin_add/<int:page>', methods=['GET', 'POST'])
@power.route('/admin_add/<int:page>-<int:page_size>', methods=['GET', 'POST'])
def admin_add(page=1, page_size=20):
    """用户角色添加"""
    g.title = u'用户角色添加'
    g.page_type = ''

    args = request.args
    errmsg = args.get('errmsg', '')
    mobile = args.get('mobile', '')
    role_id = toint(args.get('role_id', '0'))

    if errmsg:
        g.errmsg = eval(errmsg)
        log_debug('errmsg:%s'%g.errmsg)

    q = db.session.query(User.uid, User.mobile, User.nickname, UserAdmin.id, UserAdmin.role_id).\
            filter(User.uid == UserAdmin.uid).\
            filter(UserAdmin.role_id > 1)

    admin_count = get_count(q)
    admin_list  = q.order_by(UserAdmin.id.desc()).offset((page-1)*page_size).limit(page_size).all()

    role_list   = db.session.query(Role.role_id, Role.role_name).\
                    filter(Role.role_id > 1).\
                    order_by(Role.role_id.asc()).all()

    # html页面显示角色名称
    role_dict = role_name()

    pagination  = Pagination(None, page, page_size, admin_count, None)

    return render_template('power/admin_add.html.j2', f={'mobile':mobile},**locals())


@power.route('/admin_save', methods=['POST'])
def admin_save():
    """保存管理员"""
    g.title = u'保存管理员'
    g.page_type = ''

    form = request.form
    mobile  = form.get('mobile', '')
    role_id = toint(form.get('role_id', '0'))

    errmsg = {}
    form = request.form

    if not ismobile(mobile):
        errmsg['mobile'] = u'手机号码不正确'

    if role_id <= 0:
        errmsg['role_id'] = u'请选择角色'

    if errmsg:
        return redirect(url_for('power.admin_add',**locals()))

    user = User.query.filter(User.mobile == mobile).first()

    # 生成密码
    salt = randomstr(32)
    sha256_password = sha256('123456').hexdigest()
    password = sha256(sha256_password+salt).hexdigest()

    if not user:
        nickname = u'%s*****%s'% (mobile[:3] ,mobile[-3:])
        # avatar = current_app.config['DEFAULT_AVATAR']
        user = User.create(mobile=mobile,nickname=nickname, commit=True)

    up = UserPassword.query.filter(UserPassword.uid == user.uid).first()
    if not up:
       up = UserPassword.create(uid=user.uid, password=password,salt=salt)

    ua = UserAdmin.query.filter(UserAdmin.uid == user.uid).\
            filter(UserAdmin.role_id == role_id).first()

    if ua:
        ROLE_NAME = role_name()
        errmsg['mobile'] = u'%s的%s角色已经存在'% (user.nickname, ROLE_NAME.get(ua.role_id, ''))
        return redirect(url_for('power.admin_add',mobile=mobile, role_id=role_id,errmsg=errmsg))

    user_admin = UserAdmin.query.filter(UserAdmin.uid == user.uid).\
                    filter(UserAdmin.role_id == 0).first()

    if not user_admin:
        user_admin = UserAdmin.create()

    up = UserPermission.query.filter(UserPermission.uid == user.uid).\
            filter(UserPermission.role_id == role_id).first()

    if not up:
        UserPermission.create(uid=user.uid, role_id=role_id)

    user_admin.update(role_id=role_id, uid=user.uid,add_time=int(time.time()), commit=True)
    update_user_role_list()
    return redirect(url_for('power.admin_add'))


@power.route('/user_role_delete')
def user_role_delete():
    """移除用户角色"""

    id = toint(request.args.get('id', '0'))
    role_id = toint(request.args.get('role_id', '0'))

    if id <= 0 or role_id <= 0:
        return u'参数出错'

    ua = UserAdmin.query.get(id)
    if not ua:
        return '该角色已经被删除'

    user = User.query.get(ua.uid)
    if not user:
        return u'获取用户信息失败'

    if ua.role_id == 1:
        return u'超级管理员不能被移除'

    ua.update(role_id=0, commit=True)
    update_user_role_list()

    return u'ok'


@power.route('/role_admin/', methods=['GET', 'POST'])
@power.route('/role_admin/<int:page>', methods=['GET', 'POST'])
@power.route('/role_admin/<int:page>-<int:page_size>', methods=['GET', 'POST'])
def role_admin(page=1, page_size=20):
    """角色管理"""

    g.page_type = ''

    args = request.args
    role_id = toint(args.get('role_id', '0'))
    g.title = u'角色管理' if role_id <= 0 else u'角色详情'
    q = Role.query.filter(Role.role_id > 1)

    role_count = get_count(q)

    role_query_list = q.order_by(Role.role_id.asc()).offset((page-1)*page_size).limit(page_size).all()

    role = Role.query.get(role_id)

    # 获取角色权限menu_id字符串列表
    menu_id_list = db.session.query(RoleMenu.menu_id).\
                        filter(RoleMenu.menu_id == Menu.menu_id).\
                        filter(Menu.parent_id > 0).\
                        filter(RoleMenu.role_id == role_id).all()

    menu_id_list = map(lambda menu:str(menu.menu_id), menu_id_list)
    menu_id_str  = ','.join(menu_id_list)
    log_info(u'获取角色权限menu_id字符串列表:%s'% menu_id_str)
    # 获取权限列表
    # permission_list = db.session.query(Menu.menu_id, Menu.endpoint_name).\
    #                         order_by(Menu.parent_id.asc()).\
    #                         order_by(Menu.menu_id.asc()).all()

    # 获取一级菜单列表
    menu_list = db.session.query(Menu.menu_id, Menu.endpoint_name).\
                    filter(Menu.parent_id == 0).\
                    order_by(Menu.menu_id.asc()).all()

    pagination = Pagination(None, page, page_size, role_count, None)

    res = make_response(render_template('power/role_admin.html.j2',f=role if role else {},**locals()))

    res.set_cookie('goback_url', request.url)
    return res


@power.route('/role_delete')
def role_delete():
    """移除角色"""

    role_id = toint(request.args.get('role_id'))

    if role_id <= 0:
        return u'参数出错'

    UserAdmin.query.filter(UserAdmin.role_id == role_id).update({'role_id':0})

    role_menu_list = RoleMenu.query.filter(RoleMenu.role_id == role_id).all()
    for role_menu in role_menu_list:
        rm = RoleMenu.query.filter(RoleMenu.role_id == role_menu.role_id).first()
        if rm:
            rm.delete()

    user_permission_list = UserPermission.query.filter(UserPermission.role_id == role_id).all()
    [up.delete() for up in user_permission_list]

    r = Role.query.get(role_id)
    if not r:
        return '该角色已经被删除'

    r.delete(commit=True)

    return u'ok'


@power.route('/role_save', methods=['POST'])
def role_save():
    """保存角色"""
    g.title = u'保存角色'
    g.page_type = ''
    form = request.form

    desc         = form.get('desc', '')
    role_name    = form.get('role_name', '')
    role_id      = toint(form.get('role_id', '0'))
    menu_id_list = form.getlist('menu_id')
    menu_id_list = map(lambda menu_id:toint(menu_id), menu_id_list) # 现在获取的权限id列表
    errmsg = {}

    # 之前的菜单id列表
    role_menu_id_list = []
    if role_id > 0:
        role = Role.query.get(role_id)
        role_menu_id_list = db.session.query(RoleMenu.menu_id).\
                            filter(RoleMenu.menu_id == Menu.menu_id).\
                            filter(Menu.parent_id > 0).\
                            filter(RoleMenu.role_id == role.role_id).all()

        # 角色菜单id列表
        role_menu_id_list = map(lambda role_menu_id:toint(role_menu_id.menu_id), role_menu_id_list)
    else:
        role = Role.create(commit=True)

    if role.role_name == role_name and role.role_id != role_id:
        errmsg['role_name'] = u'角色名称不能重复'
        g.errmsg = errmsg
        log_debug('errmsg:%s'%g.errmsg)
        return render_template('power/role_admin.html.j2', f=form,role_id=role_id)

    # menu_id_list现在获取的权限id列表
    parent_m = None
    for menu_id in menu_id_list:
        m = Menu.query.get(menu_id)
        if not m:
            continue
        if m.parent_id > 0:
            parent_m = Menu.query.filter(Menu.menu_id == m.parent_id).first()

        q = RoleMenu.query.filter(RoleMenu.role_id == role.role_id)
        # 处理一级菜单的权限
        if parent_m:
            p_rm = q.filter(RoleMenu.menu_id == parent_m.menu_id).first()

        if not p_rm:
            # 获取权限表menu_id为0的数据
            parent_rp_0 = RoleMenu.query.filter(RoleMenu.menu_id == 0).first()

            if not parent_rp_0:
                parent_rp_0 = RoleMenu.create()
                log_info(u'### 一级菜单的权限创建')
            p_rm = parent_rp_0.update(menu_id=parent_m.menu_id, role_id=role.role_id, menu_type=1)

        # 处理二级菜单的权限
        rm = q.filter(RoleMenu.menu_id == menu_id).first()

        if rm:
            continue

        # 获取权限表menu_id为0的数据
        rm_0 = RoleMenu.query.filter(RoleMenu.menu_id == 0).first()

        if not rm_0:
            rm_0 = RoleMenu.create()
            log_info(u'### 二级菜单的权限创建')
        rm_0.update(menu_id=menu_id, role_id=role.role_id)

    # 取消的权限id列表
    cancel_menu_id_list = [menu_id for menu_id in role_menu_id_list if menu_id not in menu_id_list]
    log_info(u'### 现在的权限id列表:%s'% menu_id_list)
    log_info(u'### 之前的菜单id列表:%s'% role_menu_id_list)
    log_info(u'### 取消的角色菜单id列表:%s'% cancel_menu_id_list)
    for menu_id in cancel_menu_id_list:
        m = Menu.query.get(menu_id)
        if not m:
            continue

        # 如果没有权限则去掉主菜单
        if m.parent_id > 0:
            parent_m = Menu.get(m.parent_id)
            child_m_list = Menu.query.filter(Menu.parent_id == m.parent_id).all()
            child_m_id_list = [ toint(cm.menu_id) for cm in child_m_list ]
            rm_list = RoleMenu.query.filter(RoleMenu.role_id == role_id).\
                        filter(RoleMenu.menu_id.notin_(cancel_menu_id_list)).\
                        filter(RoleMenu.menu_id.in_(child_m_id_list)).all()

            if len(rm_list) <= 0:
                parent_rm = RoleMenu.query.filter(RoleMenu.role_id == role_id).\
                            filter(RoleMenu.menu_id == m.parent_id).first()

                if parent_rm:
                    parent_rm.update(menu_id=0, role_id=0)

        rm = RoleMenu.query.filter(RoleMenu.role_id == role.role_id).\
                        filter(RoleMenu.menu_id == menu_id).first()

        if rm:
            # 如果角色权限id列表没有在from表单获取的menu_id列表里,就把menu_id更新为0
            rm.update(menu_id=0, role_id=0)

    role = role.update(desc=desc, role_name=role_name, commit=True)

    return redirect(url_for('power.role_admin'))


def update_user_role_list():
    """更新用户角色列表"""

    session_uid = session.get('uid')
    session_role_id = session.get('role_id')

    # 更新用户角色名称显示
    role_id_list = user_role_id_list(session_uid)
    role_id_list.remove(session_role_id)
    session['role_temp_list'] = get_role_list(role_id_list, session_uid)


@power.route('/child_menu_html')
def child_menu_html():
    """子菜单选择html"""

    args  = request.args
    main_menu_id = toint(args.get('main_menu_id', '0'))
    menu_id      = toint(args.get('menu_id', '0'))
    child_menu_list = db.session.query(Menu.menu_id).\
                        filter(Menu.parent_id == main_menu_id).\
                        filter(Menu.parent_id > 0).\
                        order_by(Menu.menu_id.asc()).all()

    MENU_NAME = get_menu_name()
    child_menu_list_html = u'<select class="selectpicker form-control" name="menu_id" id="menu_id" size="1">\n<option value="0">请选择……</option>'

    option_html = u'<option value="%s" %s>%s</option>\n'
    option_html_list = [option_html % (m.menu_id, 'selected' if m.menu_id == menu_id else '', MENU_NAME.get(m.menu_id, '')) for m in child_menu_list]

    child_option_html = child_menu_list_html + ''.join(option_html_list)+ u'</select>'

    return child_option_html


@power.route('/icheckbox_check')
def icheckbox_check():
    """检测icheckbox是否选中"""

    args = request.args
    menu_id = args.get('menu_id', '')
    menu_id_str = args.get('menu_id_str', '').strip()

    menu_id_list = menu_id_str.split(',')
    log_info('### menu_id_list:%s, menu_id:%s'% (menu_id_list, menu_id))

    try:
        menu_id_list.index(u'%s'% menu_id)
        is_check = 1
    except Exception as e:
        is_check = 0

    return u'%s'% is_check
